Skip to content

Add eval scoring stack (jiwer/pyannote) with lazy imports#84

Merged
alexkroman merged 1 commit into
mainfrom
claude/focused-goodall-oxqo5g
Jun 11, 2026
Merged

Add eval scoring stack (jiwer/pyannote) with lazy imports#84
alexkroman merged 1 commit into
mainfrom
claude/focused-goodall-oxqo5g

Conversation

@alexkroman

Copy link
Copy Markdown
Collaborator

Summary

Adds support for the assembly eval command's WER/DER scoring by including jiwer and pyannote dependencies in the Homebrew formula, while refactoring the scoring modules to use lazy imports. This ensures the CLI remains lightweight for users who don't use the eval command, and allows installations missing the scoring stack to still run all other commands.

Key Changes

  • Formula updates (Formula/assembly.rb)

    • Added 20+ new Python resource dependencies: click, jiwer, joblib, narwhals, numpy, packaging, pandas, pyannote-core/database/metrics, python-dateutil, pyyaml, rapidfuzz, scikit-learn, scipy, six, sortedcontainers, threadpoolctl, tzdata
    • Enhanced test suite to verify --help works (imports full command tree) and assembly eval scoring stack is available
  • Lazy import refactoring (aai_cli/wer.py)

    • Moved jiwer import from module scope to function scope via new _transform() helper
    • Updated normalize_words() and score() to call _transform() at runtime instead of using module-level _TRANSFORM
    • Added TYPE_CHECKING import guard for type hints without runtime cost
    • Updated docstring to explain lazy import strategy
  • Import hygiene test (tests/test_import_hygiene.py) — new file

    • Validates that importing aai_cli.main does not eagerly load jiwer, rapidfuzz, pyannote, numpy, scipy, pandas, or scikit-learn
    • Runs in a subprocess to detect module-scope imports that would break the CLI on incomplete installs
  • Documentation & UX improvements

    • Updated README with Python 3.12+ requirement, clearer installation instructions, and distinction between transcribe (no extras needed) vs stream/agent (need ffmpeg/PortAudio)
    • Added authentication section with link to create free AssemblyAI account
    • Updated doctor command to mention both Debian/Ubuntu and Fedora package managers for ffmpeg and PortAudio
    • Fixed upgrade detection to use distribution names (aai-cli) instead of console command names for pipx/uv
  • Test updates

    • Enhanced test_doctor.py to verify error messages mention both HTTP 401 and 403 (corporate proxies may return 403)
    • Updated test_login.py to check for 401/403 in rejection message
    • Updated test_update_check.py comments to clarify pipx/uv upgrade by distribution name

Implementation Details

The lazy import pattern mirrors the existing der.py module's approach with pyannote. By deferring import jiwer until _transform() is called (only by normalize_words() and score()), the module stays import-cheap for the command layer. This allows the CLI to function fully on installations that lack the eval scoring stack — a critical requirement for Homebrew users who may not have all optional dependencies.

The import hygiene test runs in a fresh subprocess to catch any module-scope imports that would have broken the entire CLI on incomplete installs (as happened previously with a module-level import jiwer).

https://claude.ai/code/session_01BRpDimSLtwpYAgpHyVtJL1

…rade hints

The Homebrew formula's resource list predated `assembly eval`, so a brew
install was missing jiwer/pyannote (and packaging) — and wer.py's
module-scope `import jiwer` sat on every command's import path
(main.py -> commands/evaluate.py -> wer.py), so *every* invocation,
including --help and doctor, died with ModuleNotFoundError.

- wer.py: import jiwer lazily inside the scoring functions (mirrors
  der.py's lazy pyannote import); new test pins the CLI import chain
  free of the whole scoring stack (jiwer/rapidfuzz/pyannote/numpy/
  scipy/pandas/sklearn) in a fresh interpreter.
- Formula/assembly.rb: regenerate resources from uv.lock (19 missing:
  jiwer, rapidfuzz, the pyannote stack, numpy/scipy/pandas/scikit-learn,
  packaging, ...) and extend the brew test beyond --version: --help
  imports the full command tree, plus a direct probe of the lazily
  imported scoring deps.
- update_check.py: the pipx/uv upgrade hints used the console command
  (assembly), but pipx/uv track the distribution name — "pipx upgrade
  assembly" fails with "not installed". Now aai-cli.
- doctor/login: "rejected (HTTP 401)" now says 401/403 (is_auth_failure
  treats both as rejected; proxies often answer 403), and the
  ffmpeg/PortAudio fix hints are no longer Debian-only.
- README: signup link in Authentication, Python 3.12+ stated before the
  install commands (with a --python recovery hint), brew trust marked
  conditional, ffmpeg/PortAudio decoupled from plain transcribe, a
  warning that PyPI's assemblyai-cli is not this project, and
  `assembly stream --sample` as the no-mic streaming starter.

https://claude.ai/code/session_01BRpDimSLtwpYAgpHyVtJL1
@alexkroman
alexkroman enabled auto-merge (squash) June 11, 2026 23:57
@alexkroman
alexkroman merged commit e1f46c5 into main Jun 11, 2026
7 of 8 checks passed
@alexkroman
alexkroman deleted the claude/focused-goodall-oxqo5g branch June 11, 2026 23:59
alexkroman added a commit that referenced this pull request Jun 12, 2026
* Replace minor release bump script with patch bump

Rename scripts/bump_minor.sh to scripts/bump_patch.sh and change the
version increment from X.(Y+1).0 to X.Y.(Z+1), updating the shellcheck
list in check.sh and the release docs in AGENTS.md. Also trim the --help
sed range so it no longer prints the trailing 'set -eu' line.

https://claude.ai/code/session_01VzK2siFmrUzLziSivJqDfV

* Add libyaml dependency for pyyaml formula resource

The pyyaml resource added in #84 builds a native extension against
libyaml, and brew's FormulaAudit/ResourceRequiresDependencies check
fails without the matching depends_on line.

https://claude.ai/code/session_01VzK2siFmrUzLziSivJqDfV

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants